<template>
  <div class="communication-page">
    <div class="page-header">
      <h1 class="page-title">通信测试</h1>
      <p class="page-subtitle">测试主应用与Vue3子应用之间的通信功能</p>
    </div>

    <div class="communication-grid">
      <!-- 通信状态 -->
      <a-card title="通信状态" class="status-card">
        <template #extra>
          <api-outlined />
        </template>
        <div class="status-list">
          <div class="status-item">
            <span class="status-label">微前端环境:</span>
            <a-tag :color="isMicroFrontend ? 'green' : 'orange'">
              {{ isMicroFrontend ? '是' : '否' }}
            </a-tag>
          </div>
          <div class="status-item">
            <span class="status-label">父应用Props:</span>
            <a-tag :color="hasParentProps ? 'green' : 'gray'">
              {{ hasParentProps ? '已接收' : '未接收' }}
            </a-tag>
          </div>
          <div class="status-item">
            <span class="status-label">通信通道:</span>
            <a-tag :color="communicationReady ? 'green' : 'red'">
              {{ communicationReady ? '已建立' : '未建立' }}
            </a-tag>
          </div>
          <div class="status-item">
            <span class="status-label">消息计数:</span>
            <a-badge :count="messageCount" :overflowCount="99">
              <a-tag>消息统计</a-tag>
            </a-badge>
          </div>
        </div>
      </a-card>

      <!-- 接收到的Props -->
      <a-card title="父应用数据" class="props-card">
        <template #extra>
          <download-outlined />
        </template>
        <div v-if="parentProps" class="props-content">
          <a-descriptions :column="1" size="small" bordered>
            <a-descriptions-item label="认证Token">
              <a-typography-text :code="true" :ellipsis="{ tooltip: true }">
                {{ parentProps.data?.authToken || '未提供' }}
              </a-typography-text>
            </a-descriptions-item>
            <a-descriptions-item label="用户信息">
              <pre class="user-info">{{ JSON.stringify(parentProps.data?.userInfo, null, 2) }}</pre>
            </a-descriptions-item>
            <a-descriptions-item label="可用方法">
              <div class="methods-list">
                <a-tag 
                  v-for="method in availableMethods" 
                  :key="method"
                  color="blue"
                >
                  {{ method }}
                </a-tag>
              </div>
            </a-descriptions-item>
          </a-descriptions>
        </div>
        <a-empty v-else description="暂无父应用数据" />
      </a-card>

      <!-- 发送消息给父应用 -->
      <a-card title="发送消息" class="send-card">
        <template #extra>
          <send-outlined />
        </template>
        <a-form 
          :model="messageForm" 
          layout="vertical"
          @finish="sendMessage"
        >
          <a-form-item label="消息类型" name="type">
            <a-select v-model:value="messageForm.type" placeholder="选择消息类型">
              <a-select-option value="info">信息</a-select-option>
              <a-select-option value="warning">警告</a-select-option>
              <a-select-option value="error">错误</a-select-option>
              <a-select-option value="success">成功</a-select-option>
            </a-select>
          </a-form-item>
          <a-form-item label="消息内容" name="content">
            <a-textarea 
              v-model:value="messageForm.content"
              :rows="3"
              placeholder="输入要发送给父应用的消息"
            />
          </a-form-item>
          <a-form-item label="附加数据" name="data">
            <a-textarea 
              v-model:value="messageForm.data"
              :rows="2"
              placeholder='输入JSON格式的数据，如：{"key": "value"}'
            />
          </a-form-item>
          <a-form-item>
            <a-button 
              type="primary" 
              html-type="submit"
              :loading="sendingMessage"
              :disabled="!communicationReady"
            >
              发送消息
            </a-button>
            <a-button style="margin-left: 8px" @click="resetMessageForm">
              重置
            </a-button>
          </a-form-item>
        </a-form>
      </a-card>

      <!-- 快捷操作 -->
      <a-card title="快捷操作" class="actions-card">
        <template #extra>
          <rocket-outlined />
        </template>
        <div class="action-buttons">
          <a-button 
            type="primary" 
            @click="testParentMethod('onVueAppMount')"
            :disabled="!hasParentMethods"
          >
            <thunder-bolt-outlined />
            触发挂载事件
          </a-button>
          
          <a-button 
            danger
            @click="testParentMethod('logout')"
            :disabled="!hasParentMethods"
          >
            <logout-outlined />
            触发登出
          </a-button>
          
          <a-button 
            @click="requestUserInfo"
            :loading="loadingUserInfo"
          >
            <user-outlined />
            请求用户信息
          </a-button>
          
          <a-button 
            @click="updateChildData"
          >
            <sync-outlined />
            更新子应用数据
          </a-button>
        </div>
      </a-card>
    </div>

    <!-- 消息历史 -->
    <a-card title="消息历史" class="history-card">
      <template #extra>
        <div class="history-controls">
          <a-button size="small" @click="clearHistory">
            <delete-outlined />
            清空
          </a-button>
          <a-button size="small" @click="exportHistory">
            <export-outlined />
            导出
          </a-button>
        </div>
      </template>
      <a-timeline>
        <a-timeline-item 
          v-for="message in messageHistory" 
          :key="message.id"
          :color="getMessageColor(message.type)"
        >
          <template #dot>
            <component :is="getMessageIcon(message.type)" />
          </template>
          <div class="message-item">
            <div class="message-header">
              <span class="message-type">{{ getMessageTypeText(message.type) }}</span>
              <span class="message-time">{{ formatTime(message.timestamp) }}</span>
            </div>
            <div class="message-content">{{ message.content }}</div>
            <div v-if="message.data" class="message-data">
              <pre>{{ JSON.stringify(message.data, null, 2) }}</pre>
            </div>
          </div>
        </a-timeline-item>
      </a-timeline>
      <a-empty v-if="messageHistory.length === 0" description="暂无消息记录" />
    </a-card>

    <!-- 通信说明 -->
    <a-card title="通信机制说明" class="guide-card">
      <template #extra>
        <info-circle-outlined />
      </template>
      <a-collapse>
        <a-collapse-panel key="1" header="父子应用通信方式">
          <div class="guide-content">
            <h4>1. Props传递</h4>
            <p>父应用可以通过props向子应用传递数据和方法：</p>
            <pre class="code-block">
// 主应用配置
props: {
  data: {
    authToken: localStorage.getItem('token'),
    userInfo: JSON.parse(localStorage.getItem('userInfo') || '{}'),
  },
  methods: {
    onVueAppMount: () => console.log('Vue app mounted'),
    logout: () => { /* 登出逻辑 */ }
  }
}
            </pre>

            <h4>2. 全局事件</h4>
            <p>使用window事件进行通信：</p>
            <pre class="code-block">
// 子应用发送事件
window.dispatchEvent(new CustomEvent('vue-app-message', {
  detail: { type: 'info', content: 'Hello from Vue3!' }
}))

// 主应用监听事件
window.addEventListener('vue-app-message', (event) => {
  console.log('收到子应用消息:', event.detail)
})
            </pre>

            <h4>3. 共享状态</h4>
            <p>通过全局变量或状态管理库共享数据。</p>
          </div>
        </a-collapse-panel>
        
        <a-collapse-panel key="2" header="最佳实践">
          <div class="guide-content">
            <ul>
              <li>避免直接操作DOM，使用事件通信</li>
              <li>定义清晰的通信协议和数据格式</li>
              <li>处理通信失败的异常情况</li>
              <li>避免过度通信，影响性能</li>
              <li>使用TypeScript定义通信接口</li>
            </ul>
          </div>
        </a-collapse-panel>
      </a-collapse>
    </a-card>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted, computed } from 'vue'
import {
  ApiOutlined,
  DownloadOutlined,
  SendOutlined,
  RocketOutlined,
  ThunderboltOutlined,
  LogoutOutlined,
  UserOutlined,
  SyncOutlined,
  DeleteOutlined,
  ExportOutlined,
  InfoCircleOutlined,
  InfoOutlined,
  WarningOutlined,
  CloseCircleOutlined,
  CheckCircleOutlined
} from '@ant-design/icons-vue'
import { qiankunWindow } from 'vite-plugin-qiankun/dist/helper'

// 通信状态
const isMicroFrontend = ref(false)
const hasParentProps = ref(false)
const communicationReady = ref(false)
const messageCount = ref(0)

// 父应用数据
const parentProps = ref(null)
const availableMethods = ref([])

// 消息表单
const messageForm = reactive({
  type: 'info',
  content: '',
  data: ''
})

const sendingMessage = ref(false)
const loadingUserInfo = ref(false)

// 消息历史
const messageHistory = ref([])

// 计算属性
const hasParentMethods = computed(() => {
  return parentProps.value?.methods && Object.keys(parentProps.value.methods).length > 0
})

// 方法
const initCommunication = () => {
  // 检查是否在微前端环境
  isMicroFrontend.value = !!qiankunWindow.__POWERED_BY_QIANKUN__
  
  // 获取父应用传递的props
  if (window.__QIANKUN_PROPS__) {
    parentProps.value = window.__QIANKUN_PROPS__
    hasParentProps.value = true
    
    if (parentProps.value.methods) {
      availableMethods.value = Object.keys(parentProps.value.methods)
    }
  }
  
  communicationReady.value = isMicroFrontend.value || hasParentProps.value
  
  // 监听来自父应用的消息
  window.addEventListener('parent-to-vue', handleParentMessage)
  
  addMessage('system', '通信系统初始化完成', {
    isMicroFrontend: isMicroFrontend.value,
    hasParentProps: hasParentProps.value
  })
}

const handleParentMessage = (event) => {
  const { type, content, data } = event.detail
  addMessage('receive', `来自父应用: ${content}`, data)
  messageCount.value++
}

const sendMessage = () => {
  if (!messageForm.content) return
  
  sendingMessage.value = true
  
  try {
    let data = null
    if (messageForm.data) {
      data = JSON.parse(messageForm.data)
    }
    
    const message = {
      type: messageForm.type,
      content: messageForm.content,
      data,
      source: 'vue3-app',
      timestamp: Date.now()
    }
    
    // 发送事件给父应用
    window.dispatchEvent(new CustomEvent('vue-to-parent', {
      detail: message
    }))
    
    addMessage('send', messageForm.content, data)
    messageCount.value++
    
    // 重置表单
    resetMessageForm()
    
  } catch (error) {
    console.error('发送消息失败:', error)
    addMessage('error', '消息发送失败: JSON格式错误')
  } finally {
    sendingMessage.value = false
  }
}

const resetMessageForm = () => {
  Object.assign(messageForm, {
    type: 'info',
    content: '',
    data: ''
  })
}

const testParentMethod = (methodName) => {
  if (parentProps.value?.methods?.[methodName]) {
    try {
      parentProps.value.methods[methodName]()
      addMessage('success', `成功调用父应用方法: ${methodName}`)
    } catch (error) {
      addMessage('error', `调用父应用方法失败: ${methodName}`)
      console.error('方法调用失败:', error)
    }
  } else {
    addMessage('warning', `父应用方法不存在: ${methodName}`)
  }
}

const requestUserInfo = () => {
  loadingUserInfo.value = true
  
  // 模拟请求用户信息
  setTimeout(() => {
    const userInfo = parentProps.value?.data?.userInfo || { name: '未知用户' }
    addMessage('info', '获取用户信息成功', userInfo)
    loadingUserInfo.value = false
  }, 1000)
}

const updateChildData = () => {
  const updateData = {
    timestamp: Date.now(),
    status: 'active',
    version: '1.0.0'
  }
  
  // 通知父应用子应用数据更新
  window.dispatchEvent(new CustomEvent('vue-data-update', {
    detail: updateData
  }))
  
  addMessage('info', '子应用数据已更新', updateData)
}

const addMessage = (type, content, data = null) => {
  messageHistory.value.unshift({
    id: Date.now(),
    type,
    content,
    data,
    timestamp: Date.now()
  })
  
  // 保持最多50条记录
  if (messageHistory.value.length > 50) {
    messageHistory.value = messageHistory.value.slice(0, 50)
  }
}

const clearHistory = () => {
  messageHistory.value = []
  messageCount.value = 0
}

const exportHistory = () => {
  const data = JSON.stringify(messageHistory.value, null, 2)
  const blob = new Blob([data], { type: 'application/json' })
  const url = URL.createObjectURL(blob)
  const a = document.createElement('a')
  a.href = url
  a.download = `message-history-${Date.now()}.json`
  a.click()
  URL.revokeObjectURL(url)
}

const getMessageColor = (type) => {
  const colors = {
    send: 'blue',
    receive: 'green',
    success: 'green',
    warning: 'orange',
    error: 'red',
    info: 'blue',
    system: 'purple'
  }
  return colors[type] || 'gray'
}

const getMessageIcon = (type) => {
  const icons = {
    send: SendOutlined,
    receive: DownloadOutlined,
    success: CheckCircleOutlined,
    warning: WarningOutlined,
    error: CloseCircleOutlined,
    info: InfoOutlined,
    system: ApiOutlined
  }
  return icons[type] || InfoOutlined
}

const getMessageTypeText = (type) => {
  const texts = {
    send: '发送',
    receive: '接收',
    success: '成功',
    warning: '警告',
    error: '错误',
    info: '信息',
    system: '系统'
  }
  return texts[type] || '未知'
}

const formatTime = (timestamp) => {
  return new Date(timestamp).toLocaleString()
}

onMounted(() => {
  initCommunication()
})
</script>

<style scoped>
.communication-page {
  padding: 24px;
}

.page-header {
  text-align: center;
  margin-bottom: 40px;
}

.page-title {
  font-size: 36px;
  color: #2c3e50;
  margin-bottom: 12px;
}

.page-subtitle {
  font-size: 16px;
  color: #666;
}

.communication-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
  gap: 24px;
  margin-bottom: 24px;
}

.status-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.status-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 8px 0;
}

.status-label {
  font-weight: 500;
  color: #666;
}

.props-content {
  max-height: 300px;
  overflow-y: auto;
}

.user-info {
  background: #f5f5f5;
  padding: 8px;
  border-radius: 4px;
  font-size: 12px;
  margin: 0;
}

.methods-list {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}

.action-buttons {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 12px;
}

.history-card {
  margin-bottom: 24px;
}

.history-controls {
  display: flex;
  gap: 8px;
}

.message-item {
  padding: 8px 0;
}

.message-header {
  display: flex;
  justify-content: space-between;
  margin-bottom: 4px;
}

.message-type {
  font-weight: 500;
  color: #1890ff;
}

.message-time {
  font-size: 12px;
  color: #999;
}

.message-content {
  margin-bottom: 8px;
  color: #333;
}

.message-data {
  background: #f5f5f5;
  padding: 8px;
  border-radius: 4px;
  font-size: 12px;
}

.message-data pre {
  margin: 0;
  white-space: pre-wrap;
  word-break: break-word;
}

.guide-card {
  margin-bottom: 24px;
}

.guide-content h4 {
  color: #2c3e50;
  margin: 16px 0 8px 0;
}

.guide-content p {
  margin-bottom: 8px;
  color: #666;
}

.code-block {
  background: #f5f5f5;
  padding: 12px;
  border-radius: 4px;
  font-size: 12px;
  margin: 8px 0;
  overflow-x: auto;
}

.guide-content ul {
  padding-left: 20px;
}

.guide-content li {
  margin: 8px 0;
  color: #666;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .communication-grid {
    grid-template-columns: 1fr;
  }
  
  .action-buttons {
    grid-template-columns: 1fr;
  }
  
  .page-title {
    font-size: 28px;
  }
}
</style>